using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using TanashCMS.Business;
using TanashCMS.Business.Task;
using System.Xml;
using System.Xml.Xsl;
using System.IO;

/// <summary>
/// Summary description for Web2Xml
/// </summary>
public class Web2Xml
{
    public Web2Xml()
    {
        //
        // TODO: Add constructor logic here
        //
    }

    public static void WriteXML(TanashWebsite website)
    {
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.NewLineHandling = NewLineHandling.Entitize;
        settings.Indent = true;

        // Create a new XmlTextWriter instance
        FileStream fs = new FileStream(HttpContext.Current.Server.MapPath(website.XmlPath), FileMode.Create);

        XmlWriter w = XmlWriter.Create(fs, settings);

        w.WriteStartDocument();
        w.WriteStartElement("website");
        w.WriteAttributeString("name", website.Title);
        w.WriteAttributeString("hostname", website.HostHeader);
        w.WriteAttributeString("systemName", website.SubFolderName);
        w.WriteAttributeString("isOnline", website.IsOnline ? "1" : "0");
        w.WriteAttributeString("isBlogSite", website.getOptionValue("IsBlogSite"));
        w.WriteAttributeString("url", website.URL);
        w.WriteAttributeString("publishDate", string.Format("{0:ddd, dd MMM yyyy hh:mm:ss}", TimeZoneTask.ToLocal(website.DifferenceFromGMT, DateTime.Now)));
        w.WriteAttributeString("lastBuildDate", string.Format("{0:ddd, dd MMM yyyy hh:mm:ss}", TimeZoneTask.ToLocal(website.DifferenceFromGMT, DateTime.Now)));

        // web pages
        List<WebPage> pages = WebPage.List(website.ID, false);
        writeWebPageXml(w, "webpage", website, pages);

        // blog posts
        List<WebPage> blogposts = WebPage.GetPublishedBlogPosts(website.ID);
        writeWebPageXml(w, "blogpost", website, blogposts);

        // navigation
        List<Navigation> children = (List<Navigation>)Configuration.GetCurrentSession().CreateQuery("select n from Navigation n where n.Website.ID = " + website.ID.ToString() + " and n.ParentID = 0").List<Navigation>();
        writeNavigationXml(w, website, children);

        // inventory
        List<Category> categories = Category.List(website.ID, 0);
        w.WriteStartElement("inventory");
        writeCategoryXml(w, website, categories);

        // products in no category
        
        List<Product> products = Product.List(website.ID, 0);
        foreach (Product product in products)
        {
            w.WriteStartElement("product");
            w.WriteAttributeString("id", product.ID.ToString());
            w.WriteAttributeString("guid", product.GUID);
            w.WriteAttributeString("title", product.Title);
            w.WriteAttributeString("UPC", product.UPC);
            w.WriteAttributeString("Price", product.Price.ToString());
            w.WriteAttributeString("Discount", product.Discount.ToString());
            w.WriteAttributeString("PhotoURL", HttpContext.Current.Request.ApplicationPath.TrimEnd('/') + "/" + website.SubFolderName + "/" + product.PhotoURL);
            
            List<ProductOption> options = ProductOption.List(product.ID);
            foreach (ProductOption option in options)
            {
                w.WriteStartElement("option");
                w.WriteAttributeString("id", option.ID.ToString());
                w.WriteAttributeString("guid", option.GUID);
                w.WriteAttributeString("typeid", option.OptionType.ID.ToString());
                w.WriteAttributeString("title", option.OptionType.Title);
                w.WriteValue(option.Value);
                w.WriteEndElement();
                
            }
            if (product.HTMLContent != null)
            {
                if (product.HTMLContent != "")
                    w.WriteCData(product.HTMLContent);

            }
            w.WriteEndElement();
        }
        

        w.WriteEndElement();
        w.WriteEndElement();
        w.WriteEndDocument();
        w.Close();

        fs.Close();
        fs.Dispose();
    }

    private static void writeWebPageXml(XmlWriter w, string ElementName, TanashWebsite website, List<WebPage> pages)
    {
        foreach (WebPage page in pages)
        {
            w.WriteStartElement(ElementName);
            w.WriteAttributeString("id", page.ID.ToString());
            w.WriteAttributeString("key", page.ItemKey);
            w.WriteAttributeString("guid", page.GUID.ToString());
            w.WriteAttributeString("title", page.Title);
            w.WriteAttributeString("dateCreated", string.Format("{0:ddd, dd MMM yyyy hh:mm:ss}", TimeZoneTask.ToLocal(website.DifferenceFromGMT, page.DateCreated)));
            w.WriteAttributeString("createdYear", page.DateCreated.Year.ToString());
            w.WriteAttributeString("createdMonth", page.DateCreated.Month.ToString());
            w.WriteAttributeString("createdDay", page.DateCreated.Day.ToString());
            w.WriteAttributeString("createdHour", page.DateCreated.Hour.ToString());
            w.WriteAttributeString("createdMinute", page.DateCreated.Minute.ToString());
            w.WriteAttributeString("secure", page.IsSecure ? "1" : "0");
            w.WriteAttributeString("pageType", page.PageType.ToString());
            w.WriteAttributeString("masterPage", page.MasterPage);
            w.WriteAttributeString("homepage", website.HomePageID == page.ID ? "1" : "0");
            w.WriteAttributeString("blogpost", page.IsBlogPost ? "1" : "0");
            w.WriteAttributeString("publishDate", string.Format("{0:ddd, dd MMM yyyy hh:mm:ss}", TimeZoneTask.ToLocal(website.DifferenceFromGMT, DateTime.Now)));

            if (page.PageType == WebPageType.SmartPage)
            {
                w.WriteStartElement("components");
                List<SmartPageComponent> components = (List<SmartPageComponent>)Configuration.GetCurrentSession().CreateQuery("select c from SmartPageComponent c where c.WebPageID = " + page.ID.ToString() + " order by c.SlotIndex").List<SmartPageComponent>();
                foreach (SmartPageComponent component in components)
                {
                    w.WriteStartElement("component");
                    w.WriteAttributeString("id", component.ID.ToString());
                    w.WriteAttributeString("guid", component.GUID);
                    w.WriteAttributeString("type", component.ComponentType.ToString());
                    w.WriteAttributeString("index", component.SlotIndex.ToString());
                    w.WriteAttributeString("objectType", component.SourceObjectType.ToString());
                    w.WriteAttributeString("objectID", component.SourceObjectID.ToString());
                    w.WriteAttributeString("userControlName", component.UserControlName);
                    if (component.HtmlContent != "")
                        w.WriteCData(component.HtmlContent);
                    w.WriteEndElement();
                }
                w.WriteEndElement();
            }

            List<WebPage> children = WebPage.List(website.ID, page.ID);
            if (children.Count > 0)
                writeWebPageXml(w, ElementName, website, children);

            if (page.HTMLContent != null)
            {
                if (page.HTMLContent != "")
                    w.WriteCData(page.HTMLContent);
            }
            w.WriteEndElement();
        }
    }

    private static void writeCategoryXml(XmlWriter w, TanashWebsite website, List<Category> categories)
    {
        foreach (Category cat in categories)
        {
            w.WriteStartElement("category");
            w.WriteAttributeString("id", cat.ID.ToString());
            w.WriteAttributeString("guid", cat.GUID);
            w.WriteAttributeString("title", cat.Title);
            w.WriteAttributeString("key", System.Web.HttpUtility.UrlEncode(cat.Title));
            w.WriteAttributeString("PhotoURL", HttpContext.Current.Request.ApplicationPath.TrimEnd('/') + "/UserImages/" + website.SubFolderName + cat.PhotoURL);
            string filepath = HttpContext.Current.Server.MapPath("~/UserImages/" + website.SubFolderName + cat.PhotoURL);
            string path = Path.GetDirectoryName(filepath);
            string filename = Path.GetFileNameWithoutExtension(filepath);
            if (File.Exists(path.TrimEnd('/') + "\\" + filename + "_200.png"))
                w.WriteAttributeString("thumbnail", HttpContext.Current.Request.ApplicationPath.TrimEnd('/') + "/UserImages/" + website.SubFolderName + "/" + filename + "_200.png");

            List<Category> children = Category.List(cat.WebsiteID, cat.ID);
            if (children.Count > 0)
                writeCategoryXml(w, website, children);

            List<Product> products = Product.List(website.ID, cat.ID);
            foreach (Product product in products)
            {
                WriteProduct(w, website, ref filepath, ref path, ref filename, product);
            }
            w.WriteEndElement();
        }
    }

    private static void WriteProduct(XmlWriter w, TanashWebsite website, ref string filepath, ref string path, ref string filename, Product product)
    {
        w.WriteStartElement("product");
        w.WriteAttributeString("id", product.ID.ToString());
        w.WriteAttributeString("title", product.Title);
        w.WriteAttributeString("key", System.Web.HttpUtility.UrlEncode(product.Title));
        w.WriteAttributeString("guid", product.GUID);
        w.WriteAttributeString("UPC", product.UPC);
        w.WriteAttributeString("Price", product.Price.ToString());
        w.WriteAttributeString("Discount", product.Discount.ToString());
        w.WriteAttributeString("PhotoURL", HttpContext.Current.Request.ApplicationPath.TrimEnd('/') + "/UserImages/" + website.SubFolderName + product.PhotoURL);
        filepath = HttpContext.Current.Server.MapPath("~/UserImages/" + website.SubFolderName + product.PhotoURL);
        path = Path.GetDirectoryName(filepath);
        filename = Path.GetFileNameWithoutExtension(filepath);
        if (File.Exists(path.TrimEnd('/') + "\\" + filename + "_200.png"))
        {
            string thumbnailpath = product.PhotoURL.Replace(Path.GetFileName(product.PhotoURL), "");
            w.WriteAttributeString("thumbnail", HttpContext.Current.Request.ApplicationPath.TrimEnd('/') + "/UserImages/" + website.SubFolderName + thumbnailpath + filename + "_200.png");
        }

        List<ProductOption> options = ProductOption.List(product.ID);
        foreach (ProductOption option in options)
        {
            w.WriteStartElement("option");
            w.WriteAttributeString("id", option.ID.ToString());
            w.WriteAttributeString("guid", option.GUID);
            w.WriteAttributeString("typeid", option.OptionType.ID.ToString());
            w.WriteAttributeString("title", option.OptionType.Title);
            w.WriteValue(option.Value);
            w.WriteEndElement();
        }

        if (product.HTMLContent != null)
        {
            if (product.HTMLContent != "")
                w.WriteCData(product.HTMLContent);
        }
        w.WriteEndElement();
    }

    private static void writeNavigationXml(XmlWriter w, TanashWebsite website, List<Navigation> navigation)
    {
        foreach (Navigation navItem in navigation)
        {
            w.WriteStartElement("navigation");
            w.WriteAttributeString("id", navItem.ID.ToString());
            w.WriteAttributeString("guid", navItem.GUID);
            w.WriteAttributeString("targetType", navItem.TargetType.ToString());
            w.WriteAttributeString("targetID", navItem.TargetID.ToString());
            w.WriteAttributeString("navigateURL", navItem.NavigateURL);
            w.WriteValue(navItem.Title);
            List<Navigation> children = (List<Navigation>)Configuration.GetCurrentSession().CreateQuery("select n from Navigation n where n.Website.ID = " + website.ID.ToString() + " and n.ParentID = " + navItem.ID.ToString()).List<Navigation>();
            writeNavigationXml(w, website, children);
            w.WriteEndElement();
        }
    }

    public static string getWebsiteXml(int WebsiteID)
    {
        TanashWebsite website = Configuration.GetCurrentSession().Get<TanashWebsite>(WebsiteID);
        if (!File.Exists(HttpContext.Current.Server.MapPath(website.XmlPath)))
            WriteXML(website);

        return HttpContext.Current.Request.ApplicationPath.TrimEnd('/') + website.XmlPath;
    }

    public static void writeImagesToXml(TanashWebsite website)
    {
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.NewLineHandling = NewLineHandling.Entitize;
        settings.Indent = true;

        // something might have screwed up
        if (website == null)
        {
            // determine what website this is based on the hostname
            HttpContext context = HttpContext.Current;
            Uri uri = context.Request.Url;

            // find the hostname
            string hostname = uri.Host;
            if (hostname.Substring(0, 4) == "www.")
                hostname = hostname.Substring(4);
            website = TanashWebsite.GetByHostName(hostname);

            if (website == null)
                return;
        }

        // Create a new XmlTextWriter instance
        string imagesFolderPath = System.Web.Hosting.HostingEnvironment.MapPath(website.ImagesFolder);
        if (!Directory.Exists(imagesFolderPath))
            Directory.CreateDirectory(imagesFolderPath);

        FileStream fs = new FileStream(HttpContext.Current.Server.MapPath(website.ImagesXmlPath), FileMode.Create);

        XmlWriter w = XmlWriter.Create(fs, settings);

        DirectoryInfo folder = new DirectoryInfo(imagesFolderPath);

        w.WriteStartDocument();
        w.WriteStartElement("media");
            w.WriteStartElement("folder");
            w.WriteAttributeString("url", "/");
            writeImageFolders(w, website, folder.GetDirectories(), "");
            writeFiles(w, website, folder.GetFiles("*.*"), "");
            w.WriteValue(folder.Name);
            w.WriteEndElement();
        w.WriteEndElement();

        w.WriteEndDocument();
        w.Close();

        fs.Close();
        fs.Dispose();
    }

    private static void writeImageFolders(XmlWriter w, TanashWebsite website, DirectoryInfo[] folders, string baseUrl)
    {
        foreach (DirectoryInfo folder in folders)
        {
            w.WriteStartElement("folder");
            w.WriteAttributeString("path", baseUrl + "/");
            w.WriteAttributeString("url", baseUrl + "/" + HttpUtility.UrlPathEncode(folder.Name));
            w.WriteValue(folder.Name);
            writeImageFolders(w, website, folder.GetDirectories(), baseUrl + "/" + HttpUtility.UrlPathEncode(folder.Name));
            writeFiles(w, website, folder.GetFiles("*.*"), baseUrl + "/" + HttpUtility.UrlPathEncode(folder.Name));
            w.WriteEndElement();
        }
    }

    private static void writeFiles(XmlWriter w, TanashWebsite website, FileInfo[] files, string baseUrl)
    {
        foreach (FileInfo file in files)
        {
            if (file.Name.Contains("_200.png") || file.Name.Contains("_100.png"))
                continue;

            System.Drawing.Image img = null;
            try
            {
                img = System.Drawing.Image.FromFile(file.FullName);
            }
            catch
            {
            }

            w.WriteStartElement("image");
            //w.WriteAttributeString("systemPath", file.FullName);
            w.WriteAttributeString("path", baseUrl + "/");
            w.WriteAttributeString("url", baseUrl + "/" + HttpUtility.UrlEncode(file.Name));
            w.WriteAttributeString("extension", file.Extension);
            w.WriteAttributeString("fileName", Path.GetFileNameWithoutExtension(HttpUtility.UrlPathEncode(file.Name)));
            if (img != null)
            {
                w.WriteAttributeString("width", img.Width.ToString());
                w.WriteAttributeString("height", img.Height.ToString());
            }
            w.WriteValue(HttpUtility.UrlEncode(file.Name));
            w.WriteEndElement();
        }
    }

    public static string getNavigationHtml(TanashWebsite website)
    {
        // load navigation
        HttpContext oContext = HttpContext.Current;
        string appPath = "/TanashCMS";
        string path = oContext.Request.PhysicalApplicationPath;

        XslCompiledTransform xsl = new XslCompiledTransform(false);
        xsl.Load(path+"\\xsl\\navigation.xsl");

        XsltArgumentList args = new XsltArgumentList();
        args.AddParam("currentUrl", "", appPath + "/" + HttpContext.Current.Request.Url.Query);

        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        StringWriter sw = new StringWriter(sb);
        xsl.Transform(path + "\\xml\\" + website.SubFolderName + ".xml", args, sw);

        sw.Close();

        return sb.ToString();
    }
}
